using System;
using System.Linq;
using Generator.Model;

namespace Generator.Renderer.Public;

internal static class ForeignTypedRecord
{
    public static string Render(GirModel.Record record)
    {
        var name = Model.ForeignTypedRecord.GetPublicClassName(record);
        var internalHandleName = Model.ForeignTypedRecord.GetFullyQuallifiedOwnedHandle(record);

        return $@"
using System;
using System.Linq;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;

#nullable enable

namespace {Namespace.GetPublicName(record.Namespace)};

// AUTOGENERATED FILE - DO NOT MODIFY

{PlatformSupportAttribute.Render(record as GirModel.PlatformDependent)}
public partial class {name} : GLib.BoxedRecord, GObject.GTypeProvider, GObject.InstanceFactory, IDisposable
{{
    public {internalHandleName} Handle {{ get; }}

    public {name}({internalHandleName} handle)
    {{
        Handle = handle;
    }}

    static object GObject.InstanceFactory.Create(IntPtr handle, bool ownsHandle)
    {{
        var safeHandle = ownsHandle
            ? new {Record.GetFullyQualifiedInternalOwnedHandle(record)}(handle)
            : {Record.GetFullyQualifiedInternalOwnedHandle(record)}.FromUnowned(handle);

        return new {name}(safeHandle);
    }}

    System.IntPtr GLib.BoxedRecord.GetHandle()
    {{
        return Handle.DangerousGetHandle();
    }}

    public static GObject.Type GetGType()
    {{
        return {RenderGetGType(record.TypeFunction!)};
    }}

    public void Dispose()
    {{
        Handle.Dispose();
    }}
}}";
    }

    private static string RenderGetGType(GirModel.Function function)
    {
        return $"{Namespace.GetInternalName(function.Namespace)}.{function.Parent!.Name}.{Function.GetName(function)}()";
    }
}
